import { getToSkipOAUrlService } from '@/api/commodity/common';
import { operationSwitchSearchService } from '@/api/public';
import { toFixedCustomize } from './bizUtils';

import Vue from 'vue';
const _this = Vue.prototype;

// 根据map集合获取其值的集合
const getArraysByMaps = (maps) => {
  const values = maps.values();
  let arrays = [];
  for (let item of values) {
    arrays.push(item);
  }
  return arrays;
}
/**
 * 获取map方法返回的无undefined集合
 * @param {要进行map方法处理的集合} list
 * @param {map方法返回集合的key，默认是uuid} dimensionKey
 */
const getListByReturnMapKey = (list, dimensionKey = 'uuid') => {
  return list.map(item => item[dimensionKey]).filter(item => item);
}
/**
 * 获取集合根据map集合的维度
 * @param {要进行解析的map集合} maps
 * @param {map方法返回集合的key，默认是uuid} dimensionKey
 */
const getListByMapDimensionKey = (maps, dimensionKey = 'uuid') => {
  return getListByReturnMapKey(getArraysByMaps(maps), dimensionKey);
}
/**
 * 根据当前值获取回显文本
 * @param {* 当前要判断的值} val
 * @param {* 值为1的文本，默认为是} firstText
 * @param {* 值为2的文本，默认为否} secondText
 */
const getEchoTextByValue = ({ val, firstText = '是', secondText = '否' }) => {
  if (!val) { return '' }
  const valMappingText = {
    '1': firstText,
    '2': secondText
  }
  return valMappingText[val] || '';
}

/**
 * 获取下拉options的回显值
 * @param {*} val 当前id值 any
 * @param {*} options 当前options集合 Array
 * @param {*} valKey 当前options的value的key名称 String
 * @param {*} labelKey 当前options的label的key名称 String
 * @returns 回显文本值 any
 */
const getEchoByOptions = (val, options, valKey = 'value', labelKey = 'label') => {
  const result = options.find(item => item[valKey] === val);
  if (result) { return result[labelKey]; }
  return '';
}

// 获取重新处理后的表格字段-给表尾字段组件使用
/**
 * 根据获取的数据构成表尾字段组件需要的数据集合 *
 * @data 表尾字段原始数据
 * @keys 表尾字段对应key集合
 */
const getFooterFieldsByReprocessed = (data, keys) => {
  const INFACT_KEYS = {
    recordNo: keys?.recordNo ?? 'recordNo', // 单据号
    commitState: keys?.commitState ?? 'commitState', // 审核状态
    commitStateStr: keys?.commitStateStr ?? 'commitStateStr', // 审核状态文本
    pusherName: keys?.pusherName ?? 'pusherName', // 提交人
    pushTime: keys?.pushTime ?? 'pushTime', // 提交时间
    pusherDeptName: keys?.pusherDeptName ?? 'pusherDeptName', // 提交部门
    pusherAreaName: keys?.pusherAreaName ?? 'pusherAreaName', // 区域（提交人区域）
    auditorName: keys?.auditorName ?? 'auditUserName', // 审批人
    auditTime: keys?.auditTime ?? 'opeTime', // 审批时间
    auditReason: keys?.auditReason ?? 'reason', // 原因（审批通过为审批原因，审批失败为审批失败原因）
    reasonLabel: keys?.reasonLabel ?? 'reasonLabel' // 原因标题（默认没有，通过组件生成；特殊标签在此维护）
  }
  if (!data) { return {}; }
  const footerFields = {
    recordNo: data[INFACT_KEYS.recordNo],
    commitState: data[INFACT_KEYS.commitState],
    commitStateStr: data[INFACT_KEYS.commitStateStr],
    pusherName: data[INFACT_KEYS.pusherName],
    pushTime: data[INFACT_KEYS.pushTime],
    pusherDeptName: data[INFACT_KEYS.pusherDeptName],
    pusherAreaName: data[INFACT_KEYS.pusherAreaName],
    auditorName: data[INFACT_KEYS.auditorName],
    auditTime: data[INFACT_KEYS.auditTime],
    auditReason: data[INFACT_KEYS.auditReason],
    reasonLabel: data[INFACT_KEYS.reasonLabel]
  };
  return footerFields;
}
/**
 * 根据searchType获取特殊所需接口入参searchParam
 * @param {* 表单item集合} list
 * @param {* 表单formData数据} data
 */
const getSearchParamBySearchType = (list, data) => {
  return _.cloneDeep(list).reduce((value, item) => {
    value.push({
      name: item.prop,
      value: data[item.prop]
    }, {
      name: `${item.prop}_q`,
      value: item.searchType || 'Like'
    })
    return value;
  }, []);
}
/**
 * 获取当前集合不符合判断条件的对象的标识名集合字符串
 * @param {* 判断当前值符合条件的回调函数} isEligibleVal Function
 * @param {* 获取要返回错误item的标识名称} getTagName Function
 * @param {* 当前要判断的集合} list Array
 * @return {* 不符合判断条件的对象的标识名集合字符串} String
 */
const getTagNamesByIneligibleVal = isEligibleVal => getTagName => list => list
  .filter(item => !isEligibleVal(item))
  .map(item => getTagName(item))
  .filter(item => item)
  .join('，');
// 获取不符合售价价格组的校验条件的城市名集合
const getCityNamesByPriceIneligibleRatio = getTagNamesByIneligibleVal(
  item => toFixedCustomize(item.rate) >= 0.6 && toFixedCustomize(item.rate) <= 5
)(item => item.groupName);
// 获取不符合进价参照城市价格比例的校验条件的城市名集合
const getCityNamesByPurchaseIneligibleRatio = getTagNamesByIneligibleVal(
  item => [item.buyPriceRatio, item.costPriceRatio].every(val => toFixedCustomize(val) >= 0.6 && toFixedCustomize(val) <= 5)
)(item => item.saleCityName);

/**
 * SKU信息-获取计算后的SKU体积
 * @param {* 当前表格行数据} row Object
 * @param {* 字段标识} type Object
 * @param {* 起始标识（新增时，没有end）} start String
 * start - 层级包装层数标识
 * single -- 单层； one 一层； two 二层； three 三层
 * @param {* 末尾标识（修改时，有end，值为Update，表示现值）} end String
 * @return {* 计算后的体积} String
 */
const getSkuVolumnByCalculate = ({ row, type }) => {
  const { start, end } = type ?? {};
  const MIN_VOLUMN = 0.000001; // 最小体积值
  const edge1 = parseFloat(row[type ? `${start}Edge1${end || ''}` : 'edge1']); // 最长边
  const edge2 = parseFloat(row[type ? `${start}Edge2${end || ''}` : 'edge2']); // 次长边
  const edge3 = parseFloat(row[type ? `${start}Edge3${end || ''}` : 'edge3']) // 最短边
  const edgeList = [edge1, edge2, edge3];
  const hasNaN = edgeList.some(item => isNaN(item)); // 长度单位有非法值
  const hasEmptyValue = edgeList.some(item => !item && item !== 0); // 长度单位有非0的空值
  const hasZero = edgeList.some(item => item === 0);
  if (hasNaN || hasEmptyValue) { return ''; } // 有边界情况存在返回空（不进行计算）
  if (hasZero) { return '0'; }; // 有长度为0时返回0
  const floatVolume = (edge1 * edge2 * edge3) / 1000000; // 体积计算
  const volumn = toFixedCustomize(floatVolume, 1000000) || MIN_VOLUMN; // 最终体积数值
  return volumn.toString();
}

/**
 * 获取配置后的表列集合
 * @param {* 当前表列集合} list Array
 * @param {* 字段标识集} keys Object
 * @param {* column - 标题key} titleKey String
 * @param {* column - 标识key} keyKey String
 * @param {* column - 是否展示key} showKey String
 * @param {* column - 是否固定key} fixedKey String
 */
const getConfigColumns = (list, keys) => {
  let { titleKey, keyKey, showKey, fixedKey } = keys || {};
  titleKey = titleKey || 'columnName';
  keyKey = keyKey || 'columnNameStr';
  showKey = showKey || 'isShow';
  fixedKey = fixedKey || 'fixedColumnNum';
  return list
    .filter(item => item[showKey])
    .map((item, index) => ({
      ...item,
      title: item[titleKey],
      key: item[keyKey],
      fixed: index < item[fixedKey]
    }));
}
/**
 * 获取供应商和税类相关信息
 * @param {* 数据源} data Object
 * @returns Object
 */
const getSupplyRelativeInfo = (data) => {
  const {
    supplyUuid,
    supplyName,
    whoPayFreight,
    supplierCode,
    supplierName,
    supMainCategoryId,
    supMainCategoryName,
    supManagerHrAreaName,
    freightPayer,
    taxRate,
    invoiceType,
    invoiceTypeName
  } = data;
  return {
    supplyInfo: {
      supplierCode: supplierCode || supplyUuid,
      supplierName: supplierName || supplyName,
      supMainCategoryId,
      supMainCategoryName,
      supManagerHrAreaName,
      freightPayer: freightPayer || whoPayFreight
    },
    taxRateInfo: { taxRate, invoiceType, invoiceTypeName }
  }
}

// 获取OA页面地址跳转进行操作
export const getOAUrlToAction = async (oaRequestId, loadingFn) => {
  const data = { oaRequestId };
  const retData = await getToSkipOAUrlService(data, loadingFn);
  if (retData) {
    window.open(retData, '_blank');
  }
}

// 获取初始化的formData
export const getInitFormData = (formItems) => {
  const initData = formItems.reduce((value, item) => {
    value[item.prop] = item.defaultVal ?? '';
    return value;
  }, {});
  return initData;
}

export const openConfirmError = (callback, { content, title, options } = {}) => {
  if (!content) content = '存在禁止提交原因，无法提交单据，请在详情页中查看具体原因'
  if (!title) title = '提交错误提示'
  if (!options) options = {
    type: 'warning',
    showCancelButton: false,
    closeOnPressEscape: false,
    showClose: false
  }
  if (!callback) callback = () => {}
  _this.$confirm(content, title, options).then(() => { callback() })
}

export const openConfirmTips = (
  onSuccess = () => {},
  onCancel = () => {},
  {
    content = '存在异常提示，是否仍要提交？',
    title = '提交异常提示',
    options = { type: 'warning', cancelButtonText: '查看详情' }
  } = {},
) => {
  _this.$confirm(content, title, options)
    .then(() => { onSuccess() })
    .catch(() => { onCancel() })
}

// 获取单据页能否操作状态
export const getCanOpeState = async operation => {
  const data = { operation }
  const res = await operationSwitchSearchService(data)
  if (res?.retData == '2') {
    _this.$notify({
      title: '警告',
      message: '系统维护中，单据不可操作。请联系管理人员进行处理。',
      type: 'warning'
    })
    return false
  }
  return true
}

// 商品基础获取设置资质名称
export const getQualificationTypeName = item => {
  let qualificationTypeName = item.qualificationTypeName
  qualificationTypeName = item.mustHave === '1'
    ? `${qualificationTypeName}（正常商品：是）`
    : qualificationTypeName
  qualificationTypeName = item.potentialMustHave === '1'
    ? `${qualificationTypeName}（潜在商品：是）`
    : qualificationTypeName
  return qualificationTypeName
}

// 获取当前是否是t4环境
export const isT4Environment = () => /.t4/.test(window.location.host)

export {
  getArraysByMaps,
  getListByReturnMapKey,
  getListByMapDimensionKey,
  getEchoTextByValue,
  getFooterFieldsByReprocessed,
  getSearchParamBySearchType,
  getCityNamesByPriceIneligibleRatio,
  getCityNamesByPurchaseIneligibleRatio,
  getSkuVolumnByCalculate,
  getConfigColumns,
  getEchoByOptions,
  getSupplyRelativeInfo
}

export { CustomEnum, TableInfo } from './classUtils'
